<template>
  <div>
    <!-- 添加一个顶部 加载框 -->
    <div class="top-loading">
      <div class="loading-container">
        <div class="loading-icon"></div>
        <div class="loading-text">{{ blueToothTip }}</div>
      </div>
    </div>
    <div class="bluetooth-container">
      <h2 class="bluetooth-title">
        请选择蓝牙设备进行打印
        <span class="bluetooth-search" @click="searchDevices">搜索</span>
      </h2>
      <p class="bluetooth-hint">推荐使用低功耗蓝牙打印机，推荐型号：p_11</p>
      <div class="bluetooth-list">
        <div class="bluetooth-header">
          <div class="device-name">设备名称</div>
          <div class="device-status">设备状态</div>
        </div>
        <div
          v-for="(item, index) in matchDevice"
          :key="index"
          class="bluetooth-item"
          @click="handlePrint(item.id, index)"
        >
          <div class="device-name">{{ item.name }}</div>
          <div class="device-status">
            {{ item.device_status === 1 ? "可用" : "不可用" }}
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "bluetooth",
  props: {
    vehicleItem: {
      type: Object,
      default: {}
    }
  },
  data() {
    return {
      BleDevice: null,
      matchAddress: [],
      unmatchAddress: [],
      matchDevice: [],
      loading: true,
      blueToothTip: "正在搜索蓝牙设备..."
    };
  },
 
  mounted() {
    setTimeout(() => {
      // this.searchDevices();
      this.initBluetooth();
    });
  },
  methods: {
    // 获取当前时间
    getCurrentTime() {
      var date = new Date();
      var year = date.getFullYear();
      var month = date.getMonth() + 1;
      var day = date.getDate();
      var hour = date.getHours();
      var minute = date.getMinutes();
      var second = date.getSeconds();
      return (
        year +
        "-" +
        month +
        "-" +
        day +
        " " +
        hour +
        ":" +
        minute +
        ":" +
        second
      );
    },
    async handlePrint(deviceMac, index) {
      // 处理打印逻辑
      this.blueToothTip = "处理打印逻辑...";
      if (!deviceMac) {
        this.$toast("请选择打印机");
        return;
      }
      //   获取当前的 Android 主活动实例
      this.main = plus.android.runtimeMainActivity();
      //   导入 BluetoothAdapter 类 用于管理蓝牙适配器
      this.BluetoothAdapter = plus.android.importClass(
        "android.bluetooth.BluetoothAdapter"
      );
      //   通过 plus.android.importClass 导入 java.util.UUID 类，用于生成或解析 UUID。
      let UUID = plus.android.importClass("java.util.UUID");
      //   创建一个 UUID 对象
      this.uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
      //   获取默认的蓝牙适配器。
      this.BAdapter = this.BluetoothAdapter.getDefaultAdapter();
      //   获取远程蓝牙设备。
      this.device = this.BAdapter.getRemoteDevice(deviceMac);
      //   导入 BluetoothDevice 类。
      plus.android.importClass(this.device);
      //   创建一个不安全的 RFCOMM 套接字。
      this.bluetoothSocket = this.device.createInsecureRfcommSocketToServiceRecord(
        this.uuid
      );
      //   导入 BluetoothSocket 类。
      plus.android.importClass(this.bluetoothSocket);
      //   连接到蓝牙设备
      this.bluetoothSocket.connect();
      //   保存最近连接的设备地址。
      localStorage.setItem("lastConnectAddress", deviceMac);
      //    获取输出流。
      let outputStream = this.bluetoothSocket.getOutputStream();
      //    导入 OutputStream 类。
      plus.android.importClass(outputStream);
      //   通过 plus.android.importClass 导入 java.io.OutputStreamWriter 类，用于将字符流转换为字节流。
      const OutputStreamWriter = plus.android.importClass(
        "java.io.OutputStreamWriter"
      );

      // 生成二维码
      const writer = new OutputStreamWriter(outputStream, "GBK");
      const lineLength = 32;
      const separator = "- "
        .repeat(Math.ceil(lineLength / 2))
        .substring(0, lineLength);
      await writer.write(separator + "\r\n");
      // 加粗 + 字号放大（2倍）
      await writer.write("\x1B\x45\x01"); // 开启加粗模式 (ESC E 1)
      await writer.write("\x1D\x21\x00"); // 恢复正常字号 (GS ! 0)
      await writer.write("\x1B\x61\x01"); // 居中对齐 (ESC a 1)
      await writer.write("分宜县路边停车收费凭证\r\n");
      // 恢复默认样式
      await writer.write("\x1B\x45\x00"); // 关闭加粗 (ESC E 0)
      await writer.write("\x1D\x21\x00"); // 恢复正常字号 (GS ! 0)
      await writer.write("\x1B\x61\x00"); // 恢复左对齐
      await writer.write("车牌号：" + this.vehicleItem.licensePlate + "\r\n");
      await writer.write(
        "停车地点：路侧test" + this.vehicleItem.berthNumber + "\r\n"
      );
      await writer.write("入场时间：" + this.vehicleItem.entryTime + "\r\n");
      await writer.write("离场时间：" + this.vehicleItem.exitTime + "\r\n");
      await writer.write("需要缴费：" + this.vehicleItem.fee + "\r\n");
      await writer.write(
        "停车时长：" + this.vehicleItem.parkingDuration + "\r\n"
      );
      await writer.write(separator + "\r\n");
      // 发送二维码图像到打印机
      var moduleSize = 8;
      var bytes = plus.android.invoke(deviceMac, "getBytes", "GBK");
      var length = bytes.length;
      console.log(length);
      // outputStream.write(bytes);
      writer.write(0x1d); // init
      writer.write("(k"); // adjust height of barcode
      console.log("code 长度：", length + 3, (length + 3) % 256);

      let pl = (length + 3) % 256;
      if (pl > 127) {
        pl = pl - 256;
      }
      console.log("code pl:", pl);
      writer.write(pl); // pl

      let ph = Math.floor((length + 3) / 256);
      console.log("code ph长度：", ph);
      writer.write(ph); // ph

      console.log("#5 ");
      writer.write(49); // cn
      writer.write(80); // fn
      writer.write(48); //
      writer.write(deviceMac); //主要数据部分
      console.log("#6 ");
      // 二维码纠错等级
      writer.write(0x1d);
      writer.write("(k");
      writer.write(3);
      writer.write(0);
      writer.write(49);
      writer.write(69);
      writer.write(48);
      console.log("#7 ");
      // 设置二维码块大小
      writer.write(0x1d);
      writer.write("(k");
      writer.write(3);
      writer.write(0);
      writer.write(49);
      writer.write(67);
      writer.write(moduleSize);
      console.log("#8 ");

      // 打印已缓存的数据二维码
      writer.write(0x1d);
      writer.write("(k");
      writer.write(3); // pl
      writer.write(0); // ph
      writer.write(49); // cn
      writer.write(81); // fn
      writer.write(48); // m

      console.log("#9 ");

      writer.write(0x1b);
      writer.write(0x64);
      writer.write(3); // 行数

      await writer.write(separator + "\r\n");
      await writer.write("票据号：202504291123456 \r\n");
      await writer.write("打印时间：" + this.getCurrentTime() + " \r\n");
      await writer.write("服务电话：400-123-4567 \r\n");
      await writer.write("\r\n");
      await writer.write("\r\n");
      await writer.write("\r\n");
      await writer.write("\r\n");
      await writer.write("\r\n");
      await writer.write("\r\n");
      writer.flush();
      console.log("#10 ");
      this.blueToothTip = "打印成功...";
      this.device = null; //这里关键
      this.blueToothTip = "关闭蓝牙连接...";
      this.bluetoothSocket.close();
      this.loading = false;
      this.$emit("close");
      // 释放蓝牙设备对象。
      setTimeout(() => {
        console.log("关闭蓝牙设备---->");
        this.device = null; //这里关键
        this.bluetoothSocket.close(); //必须关闭蓝牙连接否则意外断开的话打印错误
        console.log('蓝牙设备关闭---->',);
      });
    },
  
    // 蓝牙初始化 操作
    async initBluetooth() {
      console.log('开始初始化蓝牙模块---->',);
      this.blueToothTip = "初始化蓝牙模块--------";
      var _this = this;
      // 打开蓝牙
      plus.bluetooth.openBluetoothAdapter({
        // 打开蓝牙成功
        success: function(e) {
          _this.blueToothTip = "蓝牙打开成功... ";
        },
        // 打开蓝牙失败
        fail: function(e) {
          _this.blueToothTip = "蓝牙打开失败,请手动操作...";
          _this.loading = false;
        },
        // 打开蓝牙完成回调函数
        complete(e) {
          if (!e.errCode) {
            _this.blueToothTip = "初始化完成...";
            _this.blueToothTip = "开始搜索设备...";
            // 开始搜索设备
            _this.searchDevices();
          } else if (e.errCode == 10001) {
            _this.$toast({
              icon: "none",
              title: "请打开手机蓝牙"
            });
          } else {
            _this.$toast({
              icon: "none",
              title: e.errMsg
            });
          }
        }
      });
    },
    /**
     * 搜索设备
     * @param {string}  address 设备地址
     * @param {number}  index   设备索引
     */
    async searchDevices(address = "C8:47:54:BD:33:A8", index) {
      this.blueToothTip = "清空蓝牙设备列表";
      //   清空已配对 和未配对的设备列表
      this.matchDevice = [];
      // 设置状态标志 isConnecting 和 isMatching 为false
      // 禁用按钮并显示 正在搜索请稍候...

      let _this = this;

      // 开始搜索设备
      plus.bluetooth.startBluetoothDevicesDiscovery({
        // 设备搜索成功 回调
        success: function(e) {
          _this.blueToothTip = "搜索设备成功...";
        },
        // 设备搜索失败回调
        fail: function(e) {
          _this.blueToothTip = "搜索设备失败，请手动搜索...";
        },
        // 设备搜索搜索结束后的回调
        async complete(e) {
          if (!e.errCode) {
            console.log("搜索设备完成", JSON.stringify(e));
            _this.blueToothTip = "搜索设备完成...";
            let main = plus.android.runtimeMainActivity();
            // 权限检查
            _this.blueToothTip = "进行权限检查...";
            let promiseV = await _this.requestAndroidPermission(
              "android.permission.ACCESS_COARSE_LOCATION"
            );
            // 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
            if (promiseV != 1) {
              console.log("跳转到设置");
              // Toast('打印需要位置权限，正在跳转到设置界面...');
              plus.nativeUI.toast("打印需要位置权限，正在跳转到设置界面");
              _this.gotoAppPermissionSetting();
              return;
            }
            // 注册广播接收器
            _this.blueToothTip = "注册广播接收器...";
            let IntentFilter = plus.android.importClass(
              "android.content.IntentFilter"
            );
            let BluetoothAdapter = plus.android.importClass(
              "android.bluetooth.BluetoothAdapter"
            );
            let BluetoothDevice = plus.android.importClass(
              "android.bluetooth.BluetoothDevice"
            );
            let BAdapter = BluetoothAdapter.getDefaultAdapter();
            let filter = new IntentFilter();
            let bdevice = new BluetoothDevice();
            let on = null;
            let un = null;
            BAdapter.startDiscovery(); //开启搜索
            let receiver;
            receiver = plus.android.implements(
              "io.dcloud.android.content.BroadcastReceiver",
              {
                onReceive: function(context, intent) {
                  //实现onReceiver回调函数
                  plus.android.importClass(intent); //通过intent实例引入intent类，方便以后的‘.’操作
                  if (
                    intent.getAction() ==
                    "android.bluetooth.adapter.action.DISCOVERY_FINISHED"
                  ) {
                    main.unregisterReceiver(receiver); //取消监听
                    console.log("搜索结束");
                    _this.blueToothTip = "搜索结束...";
                    console.log('未找到合适的蓝牙设备---->',);
                    
                    _this.$emit("close");
                  } else {
                    // 从 intent 对象中提取一个蓝牙设备对象，并将其赋值给 _this.BleDevice
                    _this.BleDevice = intent.getParcelableExtra(
                      BluetoothDevice.EXTRA_DEVICE
                    );
                    if (_this.BleDevice.getName() == null) {
                      return;
                    }
                    let obj = {
                      id: _this.BleDevice.getAddress(),
                      name: _this.BleDevice.getName(),
                      isConnecting: false,
                      isConnected: false,
                      device_status: 0
                    };

                    if (obj.name == "P11_PRINTER") {
                      obj.device_status = "1";
                    } else {
                      obj.device_status = "0";
                    }
                    let result = _this.matchDevice.find(item => {
                      return item.name == obj.name;
                    });
                    if (!result) {
                      _this.matchDevice.push(obj);
                      _this.blueToothTip = "搜索到设备：" + obj.name;
                      _this.blueToothTip = "开始打印...";
                      _this.handlePrint(obj.id, 0);
                    }
                  }
                }
              }
            );
            filter.addAction(bdevice.ACTION_FOUND);
            filter.addAction(BAdapter.ACTION_DISCOVERY_STARTED);
            filter.addAction(BAdapter.ACTION_DISCOVERY_FINISHED);
            filter.addAction(BAdapter.ACTION_STATE_CHANGED);
            main.registerReceiver(receiver, filter); //注册监听
          }
        }
      });
    },
    gotoAppPermissionSetting() {
      var Intent = plus.android.importClass("android.content.Intent");
      var Settings = plus.android.importClass("android.provider.Settings");
      var Uri = plus.android.importClass("android.net.Uri");
      var mainActivity = plus.android.runtimeMainActivity();
      var intent = new Intent();
      intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
      var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
      intent.setData(uri);
      mainActivity.startActivity(intent);
    },
    requestAndroidPermission(permissionID) {
      return new Promise((resolve, reject) => {
        plus.android.requestPermissions(
          [permissionID], // 理论上支持多个权限同时查询，但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
          function(resultObj) {
            var result = 0;
            for (var i = 0; i < resultObj.granted.length; i++) {
              var grantedPermission = resultObj.granted[i];
              console.log("已获取的权限：" + grantedPermission);
              result = 1;
            }
            for (var i = 0; i < resultObj.deniedPresent.length; i++) {
              var deniedPresentPermission = resultObj.deniedPresent[i];
              console.log("拒绝本次申请的权限：" + deniedPresentPermission);
              result = 0;
            }
            for (var i = 0; i < resultObj.deniedAlways.length; i++) {
              var deniedAlwaysPermission = resultObj.deniedAlways[i];
              console.log("永久拒绝申请的权限：" + deniedAlwaysPermission);
              result = -1;
            }
            resolve(result);
          },
          function(error) {
            console.log("申请权限错误：" + error.code + " = " + error.message);
            resolve({
              code: error.code,
              message: error.message
            });
          }
        );
      });
    }
  }
};
</script>

<style lang="less" scoped>
.bluetooth-container {
  background-color: #ffffff;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
}

.bluetooth-title {
  font-size: 16px;
  font-weight: bold;
  color: #303133;
  margin-bottom: 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.bluetooth-hint {
  font-size: 12px;
  color: #909399;
  margin-bottom: 20px;
}

.bluetooth-list {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.bluetooth-header {
  display: flex;
  justify-content: space-between;
  padding: 10px;
  background-color: #f5f7fa;
  font-weight: bold;
  border-bottom: 1px solid #ebedf0;
  border-radius: 8px 8px 0 0;
}

.bluetooth-item {
  display: flex;
  justify-content: space-between;
  padding: 10px;
  border-bottom: 1px solid #ebedf0;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.bluetooth-item:last-child {
  border-bottom: none;
  border-radius: 0 0 8px 8px;
}

.bluetooth-item:hover {
  background-color: #f0f9eb;
}

.device-name,
.device-status {
  flex: 1;
  text-align: left;
}

.device-status {
  color: #1890ff;
}

.device-status.unavailable {
  color: #ff4d4f;
}
.bluetooth-search {
  color: #1890ff;
  font-size: 12px;
}
.top-loading {
  position: fixed; // 或 absolute，根据父容器布局决定
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5); // 半透明遮罩
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999; // 确保在所有元素之上
}

.loading-container {
  text-align: center;
  color: #fff;
}

.loading-icon {
  width: 40px;
  height: 40px;
  border: 4px solid #fff;
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin: 0 auto 10px;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
</style>
